package com.appkubes.mall.restful.application.order.order.controller;

import com.alibaba.fastjson.JSONObject;
import com.appkubes.base.core.entity.vo.UserKeyVO;
import com.appkubes.cloud.config.params.paramValid.ParamValid;
import com.appkubes.common.Response;
import com.appkubes.common.constants.BaseConstants;
import com.appkubes.common.exception.BusinessException;
import com.appkubes.common.utils.data.date.DateUtils;
import com.appkubes.mall.core.entity.MallKdCompany;
import com.appkubes.mall.core.entity.MallOrder;
import com.appkubes.mall.restful.application.common.base.BaseController;
import com.appkubes.mall.restful.application.express.service.KdCompanyService;
import com.appkubes.mall.restful.application.order.goods.service.impl.OrderGoodsServiceImpl;
import com.appkubes.mall.restful.application.order.order.entity.OrderStateEnum;
import com.appkubes.mall.restful.application.order.order.entity.dto.GetListOrderResult;
import com.appkubes.mall.restful.application.order.order.entity.dto.UserOrderResult;
import com.appkubes.mall.restful.application.order.order.entity.pojo.RentOrderInfo;
import com.appkubes.mall.restful.application.order.order.entity.vo.*;
import com.appkubes.mall.restful.application.order.order.service.OrderService;
import com.appkubes.mall.restful.application.pay.strategy.alipay.service.impl.AliPayServiceImpl;
import com.appkubes.mall.restful.application.pay.strategy.wxpay.service.WxPayService;
import com.appkubes.mall.restful.application.plugin.rent.service.PluginRentService;
import com.appkubes.mall.restful.application.system.config.service.impl.ConfigServiceImpl;
import com.appkubes.mall.restful.application.wx.model.CreditModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Api(tags = "订单模块")
@RestController
@RequestMapping({"/api/Corder", "/order"})
@Slf4j
public class OrderController extends BaseController {

    @Autowired
    ConfigServiceImpl configServiceImpl;
    @Resource
    OrderService orderService;

    @Autowired
    OrderGoodsServiceImpl orderGoodsServiceImpl;
    @Autowired
    AliPayServiceImpl aliPayServiceImpl;
    @Autowired
    WxPayService wxPayService;

    @Resource
    PluginRentService pluginRentService; //租赁模块


    @Resource
    KdCompanyService kdCompanyService;

    @Value("${kylin.plugin.rent.hasDeposit}")
    Boolean hasRentDeposit;

    @ApiOperation(value = "订单系统设置")
    @PostMapping("/setting")
    public Response setting(@RequestParam(defaultValue = "false") Boolean isSuperPlat) {

        Map<String, String> result = new HashMap<>();
        Map<String, String> configs = new HashMap<>();
        configs.put("devliery_day_setting", "1");
        configs.put("devliery_cost_setting", "0");
        configs.put("devliery_home_switch", "1");
        configs.put("devliery_plan_switch", "1");
        configs.put("devliery_leader_switch", "0");
        configs.put("delivery_stocking_period", "0");
        configs.put("delivery_order_plan_modify_period", "0");
        for (Map.Entry<String, String> entry : configs.entrySet()) {
            result.put(entry.getKey(), configServiceImpl.getByKey(entry.getKey(), entry.getValue()));
        }
        return Response.success(result);
    }

    @ApiOperation(value = "删除订单")
    @PostMapping("/deleteOrder")
    public Response deleteOrder(@RequestBody @Valid OrderVo orderVo, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return Response.error("参数错误");
        }
        MallOrder order = orderService.getById(orderVo.getOrderKey());
        order.setIsDelete(1);
        order.setUpdateTime(DateUtils.DateToTimestamp(new Date()));
        Boolean ret = orderService.updateById(order);
        if (ret) {
            return Response.success();
        } else {
            return this.errorResponse("删除失败");
        }
    }

    @ApiOperation(value = "获取订单状态")
    @PostMapping("/getOrderState")
    public Response getOrderState(@RequestParam(defaultValue = "") String orderKey) {
        MallOrder order = orderService.getById(orderKey);
        return Response.success((Object) order.getStatus());
    }


    @ApiOperation(value = "最近购买客户")
    @PostMapping("/getNewOrders")
    public Response getNewOrders() {
        List<UserOrderResult> list = new ArrayList<>();
        return imgResponse(list);
    }


    @ApiOperation(value = "获取订单详情")
    @PostMapping("/getOrder")
    public Response getOrder(@RequestBody @ParamValid OrderVo orderVo) {

        GetListOrderResult getListOrderResult = new GetListOrderResult();

        MallOrder model = orderService.getById(orderVo.getOrderKey());
        BeanUtils.copyProperties(model, getListOrderResult);

        if (!StringUtils.isEmpty(getListOrderResult.getSendKdCode())) {
            MallKdCompany company = kdCompanyService.get(getListOrderResult.getSendKdCode());
            if (company != null) {
                getListOrderResult.setKdCompanyName(company.getName());
            }
        }

        getListOrderResult.setOrdergoodses(orderGoodsServiceImpl.getOrderGoodsByOrderKey(orderVo.getOrderKey()));
        return imgResponse(getListOrderResult);
    }

    @ApiOperation(value = "获取订单列表")
    @PostMapping("/getOrders")
    public Object getOrders(@RequestBody @ParamValid OrderPageInfoVo orderPageInfoVo) {
        StringBuffer sb = new StringBuffer();
        sb.append(" o.is_delete=0 and o.user_key='" + orderPageInfoVo.getUserKey() + "'");
        if (!StringUtils.isEmpty(orderPageInfoVo.getState())) {
            sb.append(" and (o.status='" + orderPageInfoVo.getState() + "'");
            if (orderPageInfoVo.getState().equals("completed")) {
                sb.append(" OR (o.status in ('arrive', 'completed') AND o.is_partially_compelete=1)");
            }
            sb.append(")");
            if (orderPageInfoVo.getState().equals("unPay")) {
                sb.append(" AND o.pay_status = 0");
            }
        }
        System.out.println(sb.toString());
        System.out.println(orderPageInfoVo.getPage());
        List<GetListOrderResult> orders = orderService.getList(sb.toString(), orderPageInfoVo.getPage(), orderPageInfoVo.getLimit());
        for (GetListOrderResult model : orders) {
            model.setOrdergoodses(orderGoodsServiceImpl.getOrderGoodsByOrderKey(model.getOrderKey()));
        }
        return imgResponse(orders);
    }


    @ApiOperation(value = "订单取消")
    @PostMapping("/cancelOrder")
    @Transactional(rollbackFor = Exception.class)
    public Object cancelOrder(@RequestBody OrderVo orderVo) {
        MallOrder order = orderService.getById(orderVo.getOrderKey());
        if (order == null) {
            return this.errorResponse("未找到订单");
        }
        if (!order.getStatus().equals(OrderStateEnum.UNPAY.value())) {
            return this.errorResponse("取消失败");
        }
        try {
            Boolean ret = orderService.cancel(orderVo.getOrderKey());

            if ("RENT".equals(order.getFlexType())) {
                CreditModel model = new CreditModel();
                model.setUserKey(order.getUserKey());
                model.setOrderKey(order.getFlexSegment1());
                pluginRentService.cancelZuLinOrder(model);
                orderService.updateById(order);
            }
            return Response.success();
        } catch (Exception ex) {
            log.info("取消订单出错：" + ex.getMessage());
            return Response.error(ex.getMessage());
        }
    }

    @ApiOperation(value = "订单确认完成")
    @PostMapping("/completeOrder")
    public Object completeOrder(@RequestBody @Valid OrderVo orderVo, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return Response.error("参数错误");
        }

        MallOrder order = orderService.getById(orderVo.getOrderKey());
        if (order == null) {
            return this.errorResponse("未找到订单");
        }
        if (!order.getStatus().equals(OrderStateEnum.USING.value())) {
            return this.errorResponse("订单无法确认完成，联系客服");
        }
        try {
            long time = System.currentTimeMillis() / 1000;
            order.setConfirmTime((int) time);
            order.setUpdateTime((int) time);
            order.setStatus(OrderStateEnum.COMPLETED.value());
            order.setUpdateTime(DateUtils.getCurrentTimestamp());
            orderService.updateById(order);
            return Response.success();
        } catch (Exception e) {
            log.info("确认收货出错：" + e.getMessage());
            return Response.error("发现异常，事务回滚" + e.getMessage());
        }
    }

    @ApiOperation(value = "订单确认收货,进入租用")
    @PostMapping("/usingOrder")
    public Object usingOrder(@RequestBody @ParamValid OrderVo orderVo) {
        try {
            orderService.usingOrder(orderVo);
            return Response.success();
        } catch (Exception e) {
            return Response.error(e.getMessage());
        }
    }


    @ApiOperation(value = "用户取消订单")
    @PostMapping("/userCancelOrder")
    public Object userCancelOrder(@RequestParam(defaultValue = "") String orderKey) {
        try {
            orderService.applyCancelOrder(orderKey);
            return Response.success();
        } catch (Exception e) {
            log.info("取消订单出错：" + e.getMessage());
            return this.errorResponse("申请失败");
        }
    }


    /**
     * 更新押金信息，建议后续使用分布式技术进行处理
     * @param orderVo
     * @return
     */
    @ApiOperation(value = "更新订单押金")
    @PostMapping("/updateRentOrderInfo")
    public Response updateRentOrderInfo(@RequestBody @ParamValid OrderVo orderVo) {
        MallOrder order = orderService.getById(orderVo.getOrderKey());
        if (hasRentDeposit) {
            try {
                JSONObject requestJson = pluginRentService.queryRentOrder(order.getOrderKey());
                RentOrderInfo rentOrderInfo = JSONObject.parseObject(requestJson.getString("data"), RentOrderInfo.class);
                if (OrderStateEnum.UNPAY.value().equals(order.getStatus()) && StringUtils.isEmpty(order.getFlexSegment3())) {
                    BigDecimal creditIncreaseAmount = BigDecimal.valueOf(
                            rentOrderInfo.getCreditIncreaseAmount()).divide(BigDecimal.valueOf(100));
                    order.setPayAmount(order.getPayAmount().add(creditIncreaseAmount));
                    order.setFlexSegment3(creditIncreaseAmount.toString());
                    orderService.updateById(order);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return Response.success(order);
    }

    @ApiOperation(value = "订单二次付款")
    @PostMapping("/payOrder")
    public Response payOrder(@RequestBody @ParamValid OrderRepayVO orderPayVo) {
        MallOrder order = orderService.getById(orderPayVo.getOrderKey());

        if (!BaseConstants.ORDER.UNPAY.equals(order.getStatus())) {
            return Response.error("订单已过期");
        }


        Map<String, Object> map = new HashMap<>();
        map.put("orderKey", order.getOrderKey());
        map.put("orderInfo", order);
        try {
            if (orderPayVo.getOrderType().equals("alipay")) {
                Object result = aliPayServiceImpl.pay("", order.getPayAmount(), order.getOrderKey(), "Order", 1);
                map.put("paydata", result);
                map.put("payType", "支付宝");
            } else if (orderPayVo.getOrderType().equals("alih5pay")) {
                Object result = aliPayServiceImpl.pay("", order.getPayAmount(), order.getOrderKey(), "Order", 2);
                map.put("paydata", result);
                map.put("payType", "支付宝H5");
            } else if (orderPayVo.getOrderType().equals("wxapppay")) {
                Object result = wxPayService.pay("", order.getPayAmount().setScale(0, BigDecimal.ROUND_UP), order.getOrderKey(), "Order", "商城购物", "2");
                map.put("paydata", result);
                map.put("payType", "微信App");
            } else if (orderPayVo.getOrderType().equals("wxh5pay")) {
                //微信h5支付(非微信内置浏览器)
                Object result = wxPayService.pay("", order.getPayAmount(), order.getOrderKey(), "Order", "商城购物", "3");
                map.put("paydata", result);
                map.put("payType", "微信h5");
            } else if (orderPayVo.getOrderType().equals("wxjsapi")) {
                //微信h5支付(公众号,微信内置浏览器)
                Object result = wxPayService.pay("", order.getPayAmount(), order.getOrderKey(), "Order", "充值", "4");
                map.put("paydata", result);
                map.put("payType", "微信内置浏览器");
            } else {
                //小程序支付
                Object result = wxPayService.pay("", order.getPayAmount(), order.getOrderKey(), "", "订单", "");
                map.put("paydata", result);
                map.put("payType", "小程序支付:" + "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return errorResponse("支付失败");
        }
        return Response.success(map);
    }


    @ApiOperation(value = "用户下单")
    @PostMapping("/addOrder")
    public Object addOrder(@RequestBody @ParamValid OrderAddVO orderAddVO) throws Exception {

        MallOrder order = orderAddVO.getOrder();
        OrderExtendVo orderExtendVo = orderAddVO.getOrderExtendVo();

        if ("saas_point".equals(orderExtendVo.getUserOrigin())) {
            order.setUserKey(orderExtendVo.getSaasUserid());
        }
        order.setStatus("unPay");
        order.setPeriods(orderExtendVo.getPeriods());

        List<MallOrderGoodsVo> goodsList = new ArrayList<>();
        try {
            goodsList = orderService.addOrder(order, orderAddVO);
            //添加完订单后，通知插件系统

        } catch (BusinessException e) {
            log.info("下单失败：" + e.getMessage());
            return this.errorResponse(e.getMessage());
        }

        //开始支付
        Map<String, Object> map = new HashMap<>();
        map.put("orderKey", order.getOrderKey());
        map.put("orderInfo", order);

        try {

            if (orderExtendVo.getPaymentType().equals("alipay")) {
                Object result = aliPayServiceImpl.pay("", order.getPayAmount(), order.getOrderKey(), "Order", 1);
                map.put("paydata", result);
                map.put("payType", "支付宝");
            } else if (orderExtendVo.getPaymentType().equals("alih5pay")) {
                Object result = aliPayServiceImpl.pay("", order.getPayAmount(), order.getOrderKey(), "Order", 2);
                map.put("paydata", result);
                map.put("payType", "支付宝H5");
            } else if (orderExtendVo.getPaymentType().equals("wxapppay")) {
                if (order.getPayAmount().floatValue() == 0) {
                    //，不需要支付直接通知
                    orderService.onPayCallback(order.getOrderKey());
                    map.put("status", "paySuccess");
                } else {
                    Object result = wxPayService.pay("", order.getPayAmount(), order.getOrderKey(), "Order", "充值", "2");
                    map.put("paydata", result);
                    map.put("payType", "微信App");
                }
            } else if (orderExtendVo.getPaymentType().equals("wxh5pay")) {
                //微信h5支付(非微信内置浏览器)
                Object result = wxPayService.pay("", order.getPayAmount(), order.getOrderKey(), "Order", "充值", "3");
                map.put("paydata", result);
                map.put("payType", "微信h5");
            } else if (orderExtendVo.getPaymentType().equals("wxjsapi")) {
                //微信h5支付(公众号,微信内置浏览器)
                Object result = wxPayService.pay("", order.getPayAmount(), order.getOrderKey(), "Order", "充值", "4");
                map.put("paydata", result);
                map.put("payType", "微信内置浏览器");
            } else if (orderExtendVo.getPaymentType().equals("admin")) {
                orderService.onPayCallback(order.getOrderKey());
                map.put("payType", "后台下单成功");
            } else {
                //小程序支付
                if (order.getPayAmount().floatValue() == 0 && order.getPayBalance().floatValue() > 0) {
                    orderService.onPayCallback(order.getOrderKey());
                    map.put("status", "paySuccess");
                } else {
                    Object result = wxPayService.pay("", order.getPayAmount(), order.getOrderKey(), "Order", "商城订单", order.getOrderNo());
                    map.put("paydata", result);
                    map.put("payType", "小程序支付");
                    map.put("appKey", this.getAppKey());
                    map.put("goodses", goodsList);
                    map.put("notify_url", notifyUrl);
                    map.put("state", "ready");
                }
            }
        } catch (Exception e) {
            log.error("pay error: {}", e);
            return Response.error("支付失败");
        }
        return Response.success(map);
    }

}

